package com.cjw.service.impl.resourceManage;

import com.cjw.mapper.database.ResourceMapper;
import com.cjw.mapper.database.RoleHasResourceMapper;
import com.cjw.mapper.database.RoleMapper;
import com.cjw.mapper.database.UserHasRoleMapper;
import com.cjw.pojo.dto.database.PageDTO;
import com.cjw.pojo.dto.resourceManage.ResourceListDTO;
import com.cjw.pojo.dto.resourceManage.RoleListDTO;
import com.cjw.pojo.dto.resourceManage.RoleSimpleDTO;
import com.cjw.pojo.entity.database.Resource;
import com.cjw.pojo.entity.database.Role;
import com.cjw.pojo.entity.database.RoleHasResource;
import com.cjw.pojo.entity.database.UserHasRole;
import com.cjw.pojo.query.PageQuery;
import com.cjw.pojo.query.resourceManage.AddRole;
import com.cjw.pojo.query.resourceManage.RoleQuery;
import com.cjw.pojo.query.resourceManage.UpdateRole;
import com.cjw.service.resourceManage.RoleManageService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author : cjw
 * @date: : 2022/3/26 16:32
 * @description : RoleServiceImpl
 */
@Service
public class RoleManageServiceImpl implements RoleManageService {
    @Autowired
    private RoleHasResourceMapper roleHasResourceMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private ResourceMapper resourceMapper;

    @Autowired
    private UserHasRoleMapper userHasRoleMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(AddRole addRole) {
        Role role = new Role();
        role.setName(addRole.getName());
        role.setAddTime(new Date());
        role.setUpdateTime(new Date());
        if (roleMapper.insertUseGeneratedKeys(role) != 1)
            return false;
        for (String name : addRole.getCheckList()) {
            Resource resource = new Resource();
            resource.setName(name);
            Resource selectOne = resourceMapper.selectOne(resource);
            if (selectOne == null) {
                return false;
            }
            RoleHasResource roleHasResource = new RoleHasResource();
            roleHasResource.setAddTime(new Date());
            roleHasResource.setResourceId(selectOne.getId());
            roleHasResource.setRoleId(role.getId());
            roleHasResource.setUpdateTime(new Date());
            roleHasResourceMapper.insertSelective(roleHasResource);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(Long id) {
        return roleMapper.deleteByPrimaryKey(id) == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(UpdateRole updateRole) {
        Role role = new Role();
        role.setUpdateTime(new Date());
        role.setId(updateRole.getId());
        role.setName(updateRole.getName());
        if (roleMapper.updateByPrimaryKeySelective(role) != 1)
            return false;
        RoleHasResource roleHasResource = new RoleHasResource();
        roleHasResource.setRoleId(updateRole.getId());
        roleHasResourceMapper.delete(roleHasResource);
        for (String name : updateRole.getCheckList()) {
            Resource resource = new Resource();
            resource.setName(name);
            List<Resource> resourceList = resourceMapper.select(resource);
            if (resourceList.size() == 0)
                return false;
            for (Resource resource1 : resourceList) {
                roleHasResource.setResourceId(resource1.getId());
                roleHasResource.setAddTime(new Date());
                roleHasResource.setUpdateTime(new Date());
                roleHasResourceMapper.insertSelective(roleHasResource);
            }
        }
        return true;
    }

    @Override
    public PageDTO<List<RoleListDTO>> list(RoleQuery roleQuery) {
        ArrayList<RoleListDTO> roleListDTOS = new ArrayList<>();
        PageDTO<List<RoleListDTO>> listPageDTO = new PageDTO<>();
        PageHelper.startPage(roleQuery.getPage(), roleQuery.getSize());
        Example example = new Example(Role.class);
        Example.Criteria criteria = example.createCriteria();
        if (roleQuery.getName() != null && !roleQuery.getName().trim().equals(""))
            criteria.andLike("name", "%"+roleQuery.getName()+"%");
        example.setOrderByClause("id desc");
        PageInfo<Role> resourcePageInfo = new PageInfo<>(roleMapper.selectByExample(example));
        listPageDTO.setTotal((int)resourcePageInfo.getTotal());
        for (Role role : resourcePageInfo.getList()) {
            RoleListDTO roleListDTO = new RoleListDTO();
            roleListDTO.setAddTime(role.getAddTime());
            roleListDTO.setId(role.getId());
            roleListDTO.setName(role.getName());
            roleListDTO.setUpdateTime(role.getUpdateTime());
            roleListDTOS.add(roleListDTO);
        }
        listPageDTO.setDtos(roleListDTOS);
        return listPageDTO;
    }

    @Override
    public List<RoleSimpleDTO> all() {
        ArrayList<RoleSimpleDTO> roleSimpleDTOS = new ArrayList<>();
        for (Role role : roleMapper.selectAll()) {
            RoleSimpleDTO roleSimpleDTO = new RoleSimpleDTO();
            roleSimpleDTO.setId(role.getId());
            roleSimpleDTO.setName(role.getName());
            roleSimpleDTOS.add(roleSimpleDTO);
        }
        return roleSimpleDTOS;
    }

    @Override
    public List<ResourceListDTO> resourceList() {
        ArrayList<ResourceListDTO> resourceListDTOS = new ArrayList<>();
        for (Resource resource : resourceMapper.selectAll()) {
            ResourceListDTO resourceListDTO = new ResourceListDTO();
            resourceListDTO.setId(resource.getId());
            resourceListDTO.setName(resource.getName());
            resourceListDTOS.add(resourceListDTO);
        }
        return resourceListDTOS;
    }

    @Override
    public AddRole resourceByRoleId(Long id) {
        AddRole addRole = new AddRole();
        ArrayList<String> names = new ArrayList<>();
        RoleHasResource roleHasResource = new RoleHasResource();
        roleHasResource.setRoleId(id);
        for (RoleHasResource hasResource : roleHasResourceMapper.select(roleHasResource)) {
            Resource resource = resourceMapper.selectByPrimaryKey(hasResource.getResourceId());
            names.add(resource.getName());
        }
        Role role = roleMapper.selectByPrimaryKey(id);
        addRole.setName(role.getName());
        addRole.setCheckList(names);
        return addRole;
    }

    @Override
    public String getRole(Long id) {
        UserHasRole userHasRole = new UserHasRole();
        userHasRole.setUserId(id);
        Long roleId = userHasRoleMapper.selectOne(userHasRole).getRoleId();
        Role role = roleMapper.selectByPrimaryKey(roleId);
        return role.getName();
    }
}
